home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Mania 6
/
MacMania 6.toast
/
/
Tools&Utilities
/
EnterAct Stuff
/
Minimal App7 ƒ
/
minimalApp7.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-08-29
|
27KB
|
999 lines
/* minimalApp7.c - a do-nothing-but-call Drag_on Modules application. by
Ken Earle, 1989/91/92/93. Copyright? Shirley you must be joking.
To see the hilites of calling Drag_on Modules, search this file for *****
NOTE System 7 is required to run Minimal App7. Future releases will
incorporate ever more System 7 features.
ThinkC project "MinimalApp7.π" outline:
(NOTE May 96 we have switched to CodeWarrior and the project is now call
"MinimalApp7.µ", but the setup is essentially the same as below.)
Options...; <MacHeaders>, Check Pointers, Require Protoypes
Set Project Type...; File Type APPL, Creator ???? or whatever
Size Flags:
√MultiFinder-Aware
√Background Null Events
√Suspend & Resume Events
Background Only
Get FrontClicks
Accept ChildDiedEvents
√32-Bit Compatible
√HighLevelEvent-Aware
Accept Remote HighLevelEvents
Stationery-Aware
Use TextEdit Services
Files:
minimalApp7.c - in the “Minimal App7 ƒ” folder
Call_Resource.c - also in the “Minimal App7 ƒ” folder (a copy of
the other Call_Resource.c file in “code to call Drag_ons”,
slightly modified for use with Minimal App7)
Headers: <MacHeaders> <string.h>
Libs: MacTraps, ANSI (the ordinary one, not ANSI a4 etc)
Resources: MinimalApp7.π.rsrc (just a SICN) in the “Minimal App7 ƒ” folder
NOTE place the built Minimal App7 in the same folder as the “Drag_on
Modules” folder, at the same level. Typically this will be where EnterAct is.
You should see hAWK and Read Resource under the Edit menu when you fire
this up. Options for input will be limited to “Specific file” with hAWK,
and neither module will be able to tell this little application to show
you the results of a run - you’ll have to use a real editor for that.
Other than that, everything will happen as though you were calling these
from EnterAct or some other real application.
Once you’re familiar with hAWK, it’s easy to modify a program to take its
input from a list of files in some specific file. For details see the
"hAWK User’s Manual", in the "Other ways of specifying input" section of
the "Advanced topics" chapter. For an easy way to run a hAWK program from
Minimal App7 using a list of files, see the supplied hAWK program
"$MA7_RunClip". Note though that "$MA7_RunClip" works properly only if the
actual program being run does not use preset variables, or if it is OK for
all preset variables to be null.
Minimal App7 differs from the earlier Minimal App primarily in that it
will run only under system 7. It supports concurrent hAWK execution,
meaning you can start up Minimal App7, start running a hAWK program, and
then switch to some other application and continue working. Minimal App7
will notify you when the hAWK program is done.
Minimal App7 also supports the "getclip()" function in hAWK. Since it
doesn't have a private clip, it passes the system clip. Note that most
applications do not alter the system clip until you switch out. This may
change in the future as a result of AppleScript.
As of June 96 if MA7 is started with a hAWK command line on the clip then
MA7 will launch hAWK with the command line (concurrently unless the shift
or option key is down) and quit when the program is done. Note that MA7
does not support the "MFS" (multi-file selection) input option, so either
specific input files or no input files at all should be passed in the
command line. Since the scrap is used for the command line, the hAWK
program should not be expecting to find input via getclip() either.
*/
#include <AppleEvents.h>
#include <Traps.h>
#include <GestaltEqu.h>
/*
* Some useful macros
*/
#define alpha(c) (('a'<=(c)&&(c)<='z')||('A'<=(c)&&(c)<='Z')||(c)=='_')
#define num(c) ('0'<=(c) && (c)<='9')
#define alphanum(c) (alpha(c)||num(c))
/* Some useful key constants
*/
#define CR 0x0D /* return */
#define BLANK ' ' /* a space */
#define OPTBL ' ' /* option-space */
/* kOSEvent is the event number of the suspend/resume and mouse-moved events sent
by MultiFinder. Once we determine that an event is an OSEvent, we look at the
high byte of the message sent to determine which kind it is. To differentiate
suspend and resume events we check the resumeMask bit. */
#define kOSEvent app4Evt /* event used by MultiFinder */
#define kSuspendResumeMessage 1 /* high byte of suspend/resume event message */
#define kResumeMask 1 /* bit of message field for resume vs. suspend */
#define kMouseMovedMessage 0xFA /* high byte of mouse-moved event message */
/* kExtremeNeg and kExtremePos are used to set up wide open rectangles and regions. */
#define kExtremeNeg -32768
#define kExtremePos (32767 - 1) /* required to address an old region bug */
#ifndef _Unimplemented
#define _Unimplemented 0x9F
#endif
#ifndef _WaitNextEvent
#define _WaitNextEvent 0x60
#endif
#ifndef NULL
#define NULL ((void *) 0)
#endif
#define APPLEID 15
#define FILEID 16
#define EDITID 17
#define QUIT 12
#define WindowDataPtr WindowPtr
/* Augmented record of event - see SetEventDetails() */
struct EventDetails
{
EventRecord event; /* IM 1 pg 249 */
WindowPtr mouseDownWindow;/* not necessarily front window */
Point localWhere; /* mousedown point in local coordinates */
ControlHandle whichControl;
short whatPart;
Boolean shiftDown, capsLockDown, optionDown, commandDown, doubleClick;
};
typedef struct EventDetails EventDetails;
/* --------- useful globals ---------------- */
MenuHandle appleMenu, fileMenu, editMenu;
Boolean gInBackground, gQuitting;
CursHandle IBeam, Watch;
EventDetails gEvtDetails; /* info about latest event */
Boolean daInFront; /* for scrap conversion */
/* cursor management, called by all event loops */
RgnHandle cursorRgn;
static RgnHandle arrowRgn;
static RgnHandle iBeamRgn;
/******* to handle concurrent Drag_on Modules, for version 2 or greater. */
Boolean gNotifying; /* hAWK finished with Minimal App in the background. */
Boolean gHawkIsRunning; /* If true, no quitting and less sleeping. */
NMRec gNotifyRec;
/******* The two functions from elsewhere */
/* Call_Resource.c */
extern void InitCallResources(short vRefNumForApp,
char *codeFolderName, short menuID);
/* Note "VERSION2" of CallResource() is being used. */
extern void CallResource
(short menuID,
short item,
Boolean concurrent, // set FALSE if you don't support concurrent mode
char *commandLineP // -> complete command line or NULL
);
/* Prototypes for functions defined in this file */
short main(void);
void DoStandardInits(void);
void MakeMenus(void);
Boolean DoMenu(long);
/* Apple event handlers */
pascal OSErr Handle_aevt_oapp(AppleEvent *theAppleEvent, AppleEvent *reply, long myRefCon);
pascal OSErr Handle_aevt_odoc(AppleEvent *theAppleEvent, AppleEvent *reply, long myRefCon);
pascal OSErr Handle_aevt_pdoc(AppleEvent *theAppleEvent, AppleEvent *reply, long myRefCon);
pascal OSErr Handle_aevt_quit(AppleEvent *theAppleEvent, AppleEvent *reply, long myRefCon);
OSErr MissedAEKeyword(AppleEvent *theAppleEvent);
/* some WNE functions */
void HandleModelessDialog(void);
void SetEventDetails(void);
unsigned long GetSleep(void);
void BlinkTextCursor(void);
void AdjustCursor(Point mouse, RgnHandle region);
Boolean IsMultiCursorWindow(WindowDataPtr wdPtr);
void SetWatchCursor(void);
/* support functions */
Boolean System7Available(void);
Boolean TrapAvailable(short theTrap);
TrapType GetTrapType(short theTrap);
short NumToolboxTraps(void);
void AEInstallEventHandlers(void);
void SeeIfDAIsFrontWindow(void);
/********* for concurrent mode Drag_on Module (ie hAWK), handle a single event. */
void HandleOneEvent(void);
// Command line from scrap
Boolean FireOffHawkProgram(void);
char *GetCommandLineFromScrap(void);
Boolean GenericGetName(Ptr *posPtrPtr, Ptr eofPtr, Ptr patPtr, short *patLenP);
void TellHAWKtoQuit(void);
/* Init, and the main event loop. Note there is a "one-shot" event loop
at the bottom of this file, called by hAWK during concurrent execution.
*/
short main()
{
WindowPtr whichWindow;
Point where;
short part, appVRefNum;
Boolean gotEvent;
DoStandardInits();
MakeMenus();
IBeam = GetCursor(iBeamCursor);
Watch = GetCursor(watchCursor);
if (!System7Available())
{
SysBeep(2);
SysBeep(0);
SysBeep(2);
ExitToShell();
}
AEInstallEventHandlers();
/************* Set up to call Drag_ons */
if (GetVol(NULL, &appVRefNum))
appVRefNum = 0;
InitCallResources(appVRefNum, (Ptr)"\pDrag_on Modules", EDITID);
cursorRgn = NewRgn(); /* we’ll pass WNE an empty region the 1st time thru */
arrowRgn = NewRgn();
iBeamRgn = NewRgn();
// June 96, run hAWK if command line is on clip -- we will quit after
// hAWK program is done in this case
/************* */
if (FireOffHawkProgram())
{
/****** Remove notice if hAWK finished while Minimal App was
in the background. Note that at present hAWK will not notify
us if it is run from a command line (see CallResource()).*/
if (gNotifying)
{
NMRemove(&gNotifyRec);
if (gNotifyRec.nmIcon)
ReleaseResource(gNotifyRec.nmIcon);
gNotifying = FALSE;
/* ShowResultsAfterNotify(); -not implemented */
}
ExitToShell();
}
do /* while not quitting */
{
SeeIfDAIsFrontWindow();
if (gInBackground)
{
/* handle being in the background */
;
}
gotEvent = WaitNextEvent(everyEvent, &gEvtDetails.event, GetSleep(), cursorRgn);
if (gotEvent)
{
SetEventDetails();
AdjustCursor(gEvtDetails.event.where, cursorRgn);
if (IsDialogEvent(&gEvtDetails.event))
HandleModelessDialog(); /* not implemented */
else
{
switch (gEvtDetails.event.what)
{
case mouseDown:
switch (part = FindWindow(gEvtDetails.event.where,
&gEvtDetails.mouseDownWindow))
{
case inDesk:
;
break;
case inMenuBar:
gQuitting = DoMenu(MenuSelect(gEvtDetails.event.where));
case inSysWindow:
SystemClick (&gEvtDetails.event, gEvtDetails.mouseDownWindow);
break;
case inDrag:
break;
case inZoomIn:
case inZoomOut:
break;
case inGrow:
break;
case inGoAway:
break;
case inContent:
break;
default:
break;
} /* switch FindWindow */
break;
case keyDown:
case autoKey:
break;
case updateEvt:
break;
case diskEvt:
if (HiWord(gEvtDetails.event.message) != noErr)
{
DILoad();
where.h = where.v = 85;
DIBadMount(where, gEvtDetails.event.message);
}
break;
case activateEvt:
break;
case kOSEvent:
switch((gEvtDetails.event.message >> 24) & 0xff)
{
case mouseMovedMessage:
BlinkTextCursor();
break;
case suspendResumeMessage:
/* NOT HERE if modeless in front */
gInBackground = ((gEvtDetails.event.message & resumeFlag) == 0);
/****** Remove notice if hAWK finished while Minimal App was
in the background. */
if (gNotifying)
{
NMRemove(&gNotifyRec);
if (gNotifyRec.nmIcon)
ReleaseResource(gNotifyRec.nmIcon);
gNotifying = FALSE;
/* ShowResultsAfterNotify(); -not implemented */
}
break;
} /* switch message */
break;
case kHighLevelEvent:
AEProcessAppleEvent(&gEvtDetails.event);
break;
} /* switch what */
} /* not modeless dialog */
} /* if got event */
else
BlinkTextCursor();
AdjustCursor(gEvtDetails.event.where, cursorRgn);
} while (!gQuitting);
} /* end main() */
/* Very routine stuff, though note the stack is enlarged - hAWK needs
a lot of stack. */
void DoStandardInits()
{
short i;
EventRecord event;
/********************* Adjust stack
- note long StackSpace() returns current room left on stack
at any time, if there is future trouble...*/
SetApplLimit(GetApplLimit() - 57344);
MaxApplZone();
for (i = 0; i < 18; ++i)
MoreMasters();
InitGraf(&qd.thePort);
InitFonts();
FlushEvents(everyEvent, 0);
InitWindows();
InitMenus();
TEInit();
InitDialogs(0L);
InitCursor();
for (i = 0; i < 3; ++i)
EventAvail(everyEvent, &event);
}/* end DoStandardInits() */
void MakeMenus()
{
appleMenu = NewMenu(APPLEID,(StringPtr)"\p\24");
AppendMenu(appleMenu,(StringPtr)"\p(About nothing...;(-");
AddResMenu(appleMenu,'DRVR');
InsertMenu(appleMenu,0);
fileMenu = NewMenu(FILEID,(StringPtr)"\pFile");
AppendMenu(fileMenu,(StringPtr)"\pNew;Open...;(-;Close;Save;Save as...;Revert;(-;Page Setup...;Print...;(-;Quit/Q");
InsertMenu(fileMenu,0);
editMenu = NewMenu(EDITID,(StringPtr)"\pEdit");
AppendMenu(editMenu,(StringPtr)"\pUndo/Z;(-;Cut/X;Copy/C;Paste/V;Clear");
InsertMenu(editMenu,0);
DrawMenuBar();
} /* end MakeMenus() */
/* DoMenu returns TRUE when quit selected. If hAWK is running, we force it
to quit also with a command-period. */
Boolean DoMenu(menuAndItem)
long menuAndItem;
{
short theItem;
char name[64];
theItem = LoWord(menuAndItem);
switch (HiWord(menuAndItem))
{
case APPLEID:
if (theItem > 1)
{
GetItem(appleMenu, theItem, (StringPtr)name);
OpenDeskAcc((StringPtr)name);
}
break;
case FILEID:
if (theItem == QUIT)
{
/*********** Request stop Drag_on with <Command><period> first. */
TellHAWKtoQuit();
return(TRUE);
}
break;
case EDITID:
if (theItem <= 6 && SystemEdit (theItem - 1))
return(FALSE);
/***************** Calling all Drag_ons */
if (theItem > 6)
{
CallResource( EDITID, theItem,
!gEvtDetails.shiftDown && !gEvtDetails.optionDown,
NULL);
}
break;
default:
break;
}
HiliteMenu(0);
return(FALSE);
} /* end DoMenu() */
/* ------------ Apple event handlers --------------- */
/* */
pascal OSErr Handle_aevt_oapp(AppleEvent *theAppleEvent, AppleEvent *reply, long myRefCon)
{
OSErr theErr = noErr;
theErr = MissedAEKeyword(theAppleEvent);
if (theErr) return theErr;
/* A larger app might open something here;*/
return theErr;
}
/* Minimal App7 doesn't open documents, but it might some day... */
pascal OSErr Handle_aevt_odoc(AppleEvent *theAppleEvent, AppleEvent *reply, long myRefCon)
{
AEDesc theAEDesc;
AEKeyword theAEKeyword;
FSSpec theSpec;
DescType typeCode;
FInfo fndrInfo;
OSErr theErr;
Size actualSize;
long i, count;
Boolean stationery;
theErr = AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &theAEDesc);
if (theErr) return theErr;
theErr = MissedAEKeyword(theAppleEvent);
if (theErr) return theErr;
theErr = AECountItems(&theAEDesc, &count);
if (theErr) return theErr;
for (i = 1; i <= count; ++i)
{
theErr = AEGetNthPtr(&theAEDesc, i, typeFSS, &theAEKeyword, &typeCode,
(Ptr)&theSpec, sizeof(FSSpec), &actualSize);
if (theErr) return theErr;
/* - minimal app doesn't know how to open windows.
theErr = FSpGetFInfo(&theSpec, &fndrInfo);
stationery = ((fndrInfo.fdFlags & 0x0800) != 0);
DoNewWindow(&theSpec, stationery);
*/
}
return noErr;
}
/* */
pascal OSErr Handle_aevt_pdoc(AppleEvent *theAppleEvent, AppleEvent *reply, long myRefCon)
{
return errAEEventNotHandled;
}
/* */
pascal OSErr Handle_aevt_quit(AppleEvent *theAppleEvent, AppleEvent *reply, long myRefCon)
{
OSErr theErr;
theErr = MissedAEKeyword(theAppleEvent);
if (theErr) return theErr;
TellHAWKtoQuit();
gQuitting = TRUE;
return noErr;
}
/* The logic here may seem reversed, but the goal is to check if
anything was missed. "NotFound" means the search for something missed
turned up nothing, so all was well.
*/
OSErr MissedAEKeyword(AppleEvent *theAppleEvent)
{
OSErr theErr;
DescType typeCode;
Size actualSize;
theErr = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr,
typeWildCard, &typeCode, NULL, 0, &actualSize);
if (theErr == errAEDescNotFound)
return noErr;
if (theErr == noErr)
return errAEEventNotHandled;
return theErr;
}
/* ---------- some WNE functions --------- */
void HandleModelessDialog()
{
;
}
void SetEventDetails()
{
static unsigned long oldTime = 0L;
static Point globalWhere = {-1000, -1000};
unsigned long newTime;
short dH, dV;
Point newWhere;
if (gEvtDetails.event.what == mouseDown || gEvtDetails.event.what == keyDown
|| gEvtDetails.event.what == kOSEvent)
{
gEvtDetails.shiftDown = (gEvtDetails.event.modifiers & shiftKey) != 0;
gEvtDetails.capsLockDown = (gEvtDetails.event.modifiers & alphaLock) != 0;
gEvtDetails.optionDown = (gEvtDetails.event.modifiers & optionKey) != 0;
gEvtDetails.commandDown = (gEvtDetails.event.modifiers & cmdKey) != 0;
}
if (gEvtDetails.event.what == mouseDown)
{
Delay(0L, (long *)&newTime);
newWhere = gEvtDetails.event.where;
dH = newWhere.h - globalWhere.h;
dV = newWhere.v - globalWhere.v;
if (dH < 0)
dH = -dH;
if (dV < 0)
dV = -dV;
if ((newTime - oldTime) <= GetDblTime()
&& dH <= 5 && dV <= 5)
gEvtDetails.doubleClick = TRUE;
else
gEvtDetails.doubleClick = FALSE;
globalWhere = newWhere;
GlobalToLocal (&newWhere);
gEvtDetails.localWhere = newWhere;
oldTime = newTime;
}
else
gEvtDetails.doubleClick = FALSE;
}
unsigned long GetSleep()
{
long sleep;
/******** Less sleeping if hAWK is running - adjust if you like. */
if (gHawkIsRunning)
return(2UL);
sleep = GetCaretTime();
return((unsigned long)sleep);
}
/*
* BlinkTextCursor - flash cursor
*/
void BlinkTextCursor()
{
WindowDataPtr wdPtr;
DialogPtr dP;
short item;
/* we only adjust the cursor when we are in front */
if (gInBackground)
return;
wdPtr = (WindowDataPtr) FrontWindow();
/* Your idle procedure here */
}
/* More than needed here, you can build on this for your own
cursor management. */
void AdjustCursor(Point mouse, RgnHandle region)
{
WindowDataPtr wdPtr;
Rect iBeamRect;
wdPtr = (WindowDataPtr) FrontWindow(); /* Adjust the cursor only when we are in front */
if (!gInBackground && !daInFront)
{
/* calculate regions for different cursor shapes */
SetRectRgn(iBeamRgn, 0,0,0,0);
/* start arrowRgn wide open */
SetRectRgn(arrowRgn, kExtremeNeg, kExtremeNeg, kExtremePos, kExtremePos);
/* calculate iBeamRgn */
if (IsMultiCursorWindow(wdPtr))
{
/* GetYourTextRect(wdPtr, &iBeamRect); - not implemented,
should replace next line. */
iBeamRect = ((WindowPeek)wdPtr)->port.portRect;
RectRgn(iBeamRgn, &iBeamRect);
SectRgn(iBeamRgn, ((WindowPtr)wdPtr)->visRgn, iBeamRgn);
/* make a global version of the iBeamRgn */
OffsetRgn(iBeamRgn,-((WindowPtr)wdPtr)->portBits.bounds.left,
-((WindowPtr)wdPtr)->portBits.bounds.top);
}
/* subtract other regions from arrowRgn */
DiffRgn(arrowRgn, iBeamRgn, arrowRgn);
/* change the cursor and the region parameter */
if (PtInRgn(mouse, iBeamRgn) )
{
SetCursor(*IBeam);
CopyRgn(iBeamRgn, region);
}
else
{
InitCursor();
CopyRgn(arrowRgn, region);
}
}
}
Boolean IsMultiCursorWindow(WindowDataPtr wdPtr)
{
return(FALSE);
}
/* SetWatchCursor - change cursor to watch, if available
*/
void SetWatchCursor()
{
if (Watch)
SetCursor (*Watch);
else
InitCursor();
}
/* ---------------- support functions -------------- */
#ifndef _GestaltDispatch
#define _GestaltDispatch 0xA0AD
#endif
/* */
Boolean System7Available()
{
long sysVersion;
if (!TrapAvailable(_GestaltDispatch))
return FALSE;
if (!Gestalt(gestaltSystemVersion,&sysVersion))
{
if (sysVersion >= 0x700)
return TRUE;
}
return FALSE;
}
/* */
Boolean TrapAvailable(short theTrap)
{
TrapType tType;
tType = GetTrapType(theTrap);
if (tType == ToolTrap)
{
theTrap = (theTrap & 0x07FF);
if (theTrap >= NumToolboxTraps())
theTrap = _Unimplemented;
}
return(NGetTrapAddress(theTrap, tType) != NGetTrapAddress(_Unimplemented, ToolTrap));
}
/* */
TrapType GetTrapType(short theTrap)
{
if ((theTrap & 0x0800) > 0)
return ToolTrap;
return OSTrap;
}
/* */
short NumToolboxTraps()
{
if (NGetTrapAddress(_InitGraf, ToolTrap)
== NGetTrapAddress(0xAA6E, ToolTrap))
return 0x0200;
return 0x0400;
}
void AEInstallEventHandlers()
{
AEEventHandlerUPP aHandler;
aHandler = NewAEEventHandlerProc(Handle_aevt_oapp);
AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
aHandler, 0L, FALSE);
aHandler = NewAEEventHandlerProc(Handle_aevt_odoc);
AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
aHandler, 0L, FALSE);
aHandler = NewAEEventHandlerProc(Handle_aevt_pdoc);
AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
aHandler, 0L, FALSE);
aHandler = NewAEEventHandlerProc(Handle_aevt_quit);
AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
aHandler, 0L, FALSE);
}
void SeeIfDAIsFrontWindow()
{
WindowPeek wP = (WindowPeek)FrontWindow();
if (wP && (wP->windowKind < 0))
daInFront = TRUE;
else if (daInFront)
{
daInFront = FALSE;
/*ConvertScrapIfChanged(); - not implemented */
}
}
/********* For running Drag_on's concurrently, the calling application
(here Minimal App) handles all the events while the Drag_on chugs away.
Note that quitting this app with a Quit from the menu or an AEvent
forces the hAWK program to terminate.
*/
void HandleOneEvent()
{
Point where;
Boolean gotEvent;
short part;
/* regular polling goes here */
SeeIfDAIsFrontWindow();
if (gInBackground)
{
/* handle being in the background */
;
}
gotEvent = WaitNextEvent(everyEvent, &gEvtDetails.event, GetSleep(), cursorRgn);
if (gotEvent)
{
SetEventDetails();
AdjustCursor(gEvtDetails.event.where, cursorRgn);
if (IsDialogEvent(&gEvtDetails.event))
HandleModelessDialog();
else
{
switch (gEvtDetails.event.what)
{
case mouseDown:
switch (part = FindWindow(gEvtDetails.event.where,
&gEvtDetails.mouseDownWindow))
{
case inDesk:
SysBeep(2);
break;
case inMenuBar:
// If we go, hAWK goes too.
gQuitting = DoMenu(MenuSelect(gEvtDetails.event.where));
case inSysWindow:
SystemClick(&gEvtDetails.event, gEvtDetails.mouseDownWindow);
break;
case inDrag:
break;
case inZoomIn:
case inZoomOut:
break;
case inGrow:
break;
case inGoAway:
break;
case inContent:
break;
default:
break;
} /* switch FindWindow */
break;
case keyDown:
case autoKey:
break;
case updateEvt:
break;
case diskEvt:
if (HiWord(gEvtDetails.event.message) != noErr)
{
DILoad();
where.h = where.v = 85;
DIBadMount(where, gEvtDetails.event.message);
}
break;
case activateEvt:
break;
case kOSEvent:
switch((gEvtDetails.event.message >> 24) & 0xff)
{
case mouseMovedMessage:
BlinkTextCursor();
break;
case suspendResumeMessage:
gInBackground = (gEvtDetails.event.message & resumeFlag) == 0;
break;
}
break;
case kHighLevelEvent:
AEProcessAppleEvent(&gEvtDetails.event);
break;
} /* switch */
} /* not modeless dialog */
} /* if got event */
else
BlinkTextCursor();
AdjustCursor(gEvtDetails.event.where, cursorRgn);
}
/* Run hAWK program at startup if there is a command line on the clipboard.
*/
Boolean FireOffHawkProgram(void)
{
MenuHandle menu;
Str255 name;
short numItems;
short i;
Boolean result = FALSE;
// Is hAWK available?
menu = GetMHandle(EDITID);
if (menu != NULL)
{
numItems = CountMItems(menu);
for (i = 7; i <= numItems; ++i)
{
GetItem(menu, i, name);
if ( name[0] == 4
&& name[1] == 'h'
&& name[2] == 'A'
&& name[3] == 'W'
&& name[4] == 'K' )
{
Ptr commandLineP;
commandLineP = GetCommandLineFromScrap();
if (commandLineP != NULL)
{
KeyMap k;
Boolean shiftIsDown;
Boolean optionIsDown;
GetKeys(k);
if (BitTst(&(k[0]), 61))
optionIsDown = TRUE;
if (BitTst(&(k[0]), 63))
shiftIsDown = TRUE;
CallResource( EDITID,
i,
!shiftIsDown && !optionIsDown,
commandLineP );
DisposePtr(commandLineP);
result = TRUE;
}
break;
}
}
}
return result;
}
/* Get command line for hAWK from scrap as C string, or return NULL.
*/
char *GetCommandLineFromScrap(void)
{
Handle scrapTextH; // copy of scrap text
char name[16]; // for GenericGetName
short nameLength; // ditto
long offset; // into scrap
long numChars = 0; // num text chars on scrap
long onScrap;
Ptr bPtr, // start of text
cPtr, // advances through the text
topPtr; // end of text
Ptr commandLineP = NULL;// allocated cmd line or NULL
ScrapStuff *scrapStuff;
scrapStuff = InfoScrap();
scrapTextH = NewHandle(0);
if (scrapTextH != NULL)
{
numChars = GetScrap(scrapTextH,'TEXT',&offset);
if (numChars > 7) // "hAWK -fX" is smallest command line, 8 chars
{
bPtr = *scrapTextH;
cPtr = bPtr;
topPtr = bPtr + numChars;
while (*cPtr == BLANK || (*cPtr > 0 && *cPtr <= CR)
|| *cPtr == OPTBL)
++cPtr;
nameLength = 15;
if ( GenericGetName(&cPtr, topPtr, name, &nameLength)
&& nameLength == 4 )
{
if ( (*name == 'h' || *name == 'H')
&& (*(name+1) == 'a' || *(name+1) == 'A')
&& (*(name+2) == 'w' || *(name+2) == 'W')
&& (*(name+3) == 'k' || *(name+3) == 'K') )
{
commandLineP = NewPtr(numChars + 1);
if (commandLineP != NULL)
{
// Fill in the new ptr.
BlockMove(*scrapTextH, commandLineP, numChars);
commandLineP[numChars] = '\0';
}
}
}
}
// else scrap very short or error getting scrap text
DisposeHandle(scrapTextH);
}
return commandLineP;
}
// If at a name, load it to patPtr, get length, adjust posPtr past it.
Boolean GenericGetName(Ptr *posPtrPtr, Ptr eofPtr, Ptr patPtr, short *patLenP)
{
Ptr cPtr = *posPtrPtr;
short nameLen;
short maximumLength = *patLenP;
if (maximumLength <= 0)
maximumLength = 127;
if (cPtr >= eofPtr)
return(FALSE);
if (alpha(*cPtr))
{
nameLen = 1;
*patPtr++ = *cPtr++;
while (alphanum(*cPtr) && cPtr < eofPtr && nameLen < maximumLength)
{
++nameLen;
*patPtr++ = *cPtr++;
}
*patLenP = nameLen;
*posPtrPtr = cPtr;
return(TRUE);
}
else
return(FALSE);
}
#define kPeriod 0x2f2e
/* Send a command-period to hAWK
*/
void TellHAWKtoQuit(void)
{
OSErr theErr;
EvQEl *qElPtr;
if (!gHawkIsRunning)
return;
theErr = PPostEvent(keyDown,kPeriod,&qElPtr);
if (theErr == noErr)
qElPtr->evtQModifiers = cmdKey;
}